<template>
  <div>
    <el-form label-width="100px">
      <el-form-item label="SPU名称">
        <el-input placeholder="SPU名称" v-model="spuForm.spuName"></el-input>
      </el-form-item>

      <el-form-item label="品牌">
        <!-- select收集数据收集什么 value就写什么


        vomodel写的数据是什么,会用这个数据和所有option 的value进行匹配
        如果匹配上,默认就选中这个option
        -->
        <el-select v-model="spuForm.tmId" placeholder="请选择">
          <el-option
            :value="(tm.id as number)"
            :label="tm.tmName"
            v-for="(tm, index) in trademarkList"
            :key="tm.id"
          ></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="SPU描述">
        <el-input
          placeholder="SPU描述"
          type="textarea"
          rows="4"
          v-model="spuForm.description"
        ></el-input>
      </el-form-item>

      <el-form-item label="SPU图片">
        <el-upload
          v-model:file-list="(spuImageList as any)"
          action="/app-dev/admin/product/fileUpload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleSuccess"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>

      <el-form-item label="销售属性">
        <el-select
          v-model="saleAttrIdName"
          :placeholder="
            unUsedSaleAttrList.length > 0
              ? `还有${unUsedSaleAttrList.length}未选择`
              : '没有啦!!!'
          "
        >
          <el-option
            :label="unUsedSaleAttr.name"
            :value="`${unUsedSaleAttr.id}:${unUsedSaleAttr.name}`"
            v-for="(unUsedSaleAttr, index) in unUsedSaleAttrList"
            :key="unUsedSaleAttr.id"
          ></el-option>
        </el-select>
        <el-button type="primary" @click="addSaleAttr">添加销售属性</el-button>
        <el-table :data="spuSaleAttrList" border stripe>
          <el-table-column label="序号" align="center" width="80" type="index">
          </el-table-column>
          <el-table-column label="属性名" prop="saleAttrName">
          </el-table-column>
          <el-table-column label="属性值名称列表">
            <!--  -->
            <template v-slot="{ row, $index }">
              <el-tag
                class="mx-1"
                closable
                :disable-transitions="false"
                v-for="(saleAttrValue, index) in row.spuSaleAttrValueList"
                :key="saleAttrValue.id"
                @close="row.spuSaleAttrValueList.splice(index, 1)"
              >
                {{ saleAttrValue.saleAttrValueName }}
              </el-tag>

              <!-- @keyup.enter="handleInputConfirm"
                @blur="handleInputConfirm" -->
              <el-input
                v-model="row.saleAttrValueName"
                v-if="row.isEdit"
                ref="InputRef"
                class="ml-1 w-20"
                size="small"
                style="width: 100px"
                @keyup.enter="$event.target.blur()"
                @blur="handleInputConfirm(row)"
              />

              <!-- @xxx = "message = $event" 
              emits('xxx','yangmi') -->

              <!-- $event名字不能随便写,因为是源码当中定义好的形参
                $event在原生dom事件代表事件对象
                $event在自定义事件代表触发事件传递的参数
              -->

              <!--   -->
              <el-button
                v-else
                class="button-new-tag ml-1"
                size="small"
                @click="showInput(row)"
              >
                添加
              </el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template v-slot="{ row, $index }">
              <el-button
                type="danger"
                size="small"
                icon="ele-Delete"
                @click="spuSaleAttrList.splice($index, 1)"
              ></el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="save">保存</el-button>
        <el-button @click="emits('changeState', 1)">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { storeToRefs } from "pinia";
export default defineComponent({
  name: "SpuForm", //组件名称
});
</script>
<script lang="ts" setup>
import type { BaseSaleAttrData, SpuData, SpuSaleAttrData } from "@/api/spu";
import { ref, onMounted, computed, nextTick } from "vue";
import cloneDeep from "lodash/cloneDeep";
import { Plus } from "@element-plus/icons-vue"; //ele-Plus
import { ElMessage, type UploadProps, type UploadUserFile } from "element-plus";
import spuApi from "@/api/spu";
import trademarkApi, { type TrademarkData } from "@/api/trademark";
import skuApi, { type SpuImageData } from "@/api/sku";
import { useCategoryStore } from "@/stores/category";
// 从父组件接受的spu,用来收集数据使用
const props = defineProps<{
  spu: SpuData;
}>();
const emits = defineEmits(["changeState"]);
const categoryStore = useCategoryStore();
// 下面这个spuForm就是最终我们要收集的对象
const spuForm = ref<SpuData>(cloneDeep(props.spu));

// 前三个已经收集到位,v-model
// {
// spuName: string;
// description: string;
// tmId: string | number;

// 目前先不用管,最后保存的时候去整理进去spuForm就好
// category3Id: string | number;

// 下面的两个数据 spuForm当中都是没有,全是空数组,因为这两个数据是单独发请求存储在外面的全局变量当中
// 我们一会收集的时候也是先收集在外面的两个变量数据当中,最终整理的时候再去放到spuForm当中
// spuSaleAttrList: [];
// spuImageList[];
// }

const baseSaleAttrList = ref<BaseSaleAttrData[]>([]);
const trademarkList = ref<TrademarkData[]>([]);
const spuImageList = ref<SpuImageData[]>([]);
const spuSaleAttrList = ref<SpuSaleAttrData[]>([]);

async function getUpdateSpuFormInitData() {
  // http://localhost:3000/app-dev/admin/product/baseSaleAttrList
  const promise1 = spuApi.getBaseSaleAttrList();
  // http://localhost:3000/app-dev/admin/product/baseTrademark/getTrademarkList
  const promise2 = trademarkApi.getList();
  // http://localhost:3000/app-dev/admin/product/spuImageList/945
  const promise3 = skuApi.getSpuImageList(spuForm.value.id as number);
  // http://localhost:3000/app-dev/admin/product/spuSaleAttrList/945
  const promise4 = skuApi.getSpuSaleAttrList(spuForm.value.id as number);

  // Promise.all是个方法,是函数
  // 函数:函数三要素
  // 功能:干啥              同时处理多个promise(并发不是并行)
  // 参数:传什么参数         promsie对象的数组
  // 返回值:返回啥           新的promise对象
  // 如果数组当中每个promise都成功,那么返回的新promise就成功
  // 成功的结果是数组中每个promise成功的结果组成的数组
  // 如果数组当中有一个promise失败,那么返回的新promise就失败
  // 失败的原因就是那个失败的promise的原因
  // 影响原数组吗?
  try {
    const result = await Promise.all([promise1, promise2, promise3, promise4]);
    baseSaleAttrList.value = result[0];
    trademarkList.value = result[1];

    // 这里添加name和url就是为了让upload照片墙可以正常显示图片
    let imageList = result[2];
    imageList.forEach((item) => {
      item.name = item.imgName;
      item.url = item.imgUrl;
    });

    spuImageList.value = imageList;
    spuSaleAttrList.value = result[3];
  } catch (error) {
    ElMessage.error("获取修改spu的初始化动态数据失败");
  }
}

const getAddSpuFormInitData = async () => {
  // http://localhost:3000/app-dev/admin/product/baseSaleAttrList
  const promise1 = spuApi.getBaseSaleAttrList();
  // http://localhost:3000/app-dev/admin/product/baseTrademark/getTrademarkList
  const promise2 = trademarkApi.getList();
  try {
    const result = await Promise.all([promise1, promise2]);
    baseSaleAttrList.value = result[0];
    trademarkList.value = result[1];
  } catch (error) {
    ElMessage.error("获取添加spu的初始化动态数据失败");
  }
};

// 当页面挂载完成请求获取初始化动态数据
onMounted(() => {
  if (spuForm.value.id) {
    // 修改
    getUpdateSpuFormInitData();
  } else {
    // 添加
    getAddSpuFormInitData();
  }
});

// 计算未选择的剩余的销售属性列表
// 根据所有的销售属性列表和spu自己的销售属性列表去计算
const unUsedSaleAttrList = computed(() => {
  // baseSaleAttrList  所有的销售属性列表
  // spuSaleAttrList   spu自己的
  // 从所有的列表当中过滤在spu自己的列表当中没有的
  return baseSaleAttrList.value.filter((item) => {
    return spuSaleAttrList.value.every((item1) => {
      return item1.saleAttrName !== item.name;
    });
  });
});

// const unUsedSaleAttrList = computed(() => {
//   return baseSaleAttrList.value.filter((item) =>spuSaleAttrList.value.every((item1) => item1.saleAttrName !== item.name))
// });

// 点击select收集添加销售属性(id:name)
const saleAttrIdName = ref("");
// 点击添加销售属性按钮
const addSaleAttr = () => {
  // 把刚才手机的id:name字符串切割拿到id和name
  // 把id和name变为需要的对象添加到spuSaleAttrList当中
  let [baseSaleAttrId, saleAttrName] = saleAttrIdName.value.split(":");

  let obj = {
    baseSaleAttrId,
    saleAttrName,
    spuSaleAttrValueList: [],
  };

  spuSaleAttrList.value.push(obj);

  //清空收集的串,让select选中的值不再显示
  saleAttrIdName.value = "";
};

// 点击添加销售属性值的添加按钮
const InputRef = ref();
const showInput = (row: SpuSaleAttrData) => {
  row.isEdit = true;

  nextTick(() => {
    InputRef.value.focus();
  });

  // nextTick().then(() => {

  // })
};

// 输入完成销售属性值失去焦点
const handleInputConfirm = (row: SpuSaleAttrData) => {
  let { baseSaleAttrId, saleAttrValueName } = row;

  if (saleAttrValueName?.trim() === "") {
    ElMessage.error("输入的属性值名称不能为空!!!");
    // saleAttrValueName = '' 错的
    row.saleAttrValueName = "";
    row.isEdit = false;
    return;
  }
  let isRepeat = row.spuSaleAttrValueList.some(
    (item) => item.saleAttrValueName === saleAttrValueName
  );

  if (isRepeat) {
    ElMessage.error("输入的属性值名称不能重复!!!");
    row.saleAttrValueName = "";
    row.isEdit = false;
    return;
  }

  let obj = { baseSaleAttrId, saleAttrValueName };
  row.spuSaleAttrValueList.push(obj);

  row.saleAttrValueName = "";
  row.isEdit = false;
};

const { category3Id } = storeToRefs(categoryStore);
// 点击保存按钮
const save = async () => {
  // 获取请求参数
  let spu = spuForm.value;
  // 整理参数
  //   1>整理category3Id，修改里面是有的，但是添加里面需要收集，因此不管是修改还是添加都给一个
  // 需要从store当中去拿
  spu.category3Id = category3Id.value;
  //   2>整理图片列表
  //   新老图片格式上面有
  spu.spuImageList = spuImageList.value.map((item) => {
    return {
      imgName: item.name as string,
      imgUrl: item.imgUrl || (item.response.data as string),
    };
  });
  //   3>整理spu的销售属性列表
  //   删除每个销售属性身上的 isEdit和saleAttrValueName
  spuSaleAttrList.value.forEach((item) => {
    delete item.isEdit;
    delete item.saleAttrValueName;
  });
  spu.spuSaleAttrList = spuSaleAttrList.value;

  // 发请求
  try {
    await spuApi.saveSpuInfo(spu);
    // 成功
    ElMessage.success("保存spu成功");
    emits("changeState", 1);
  } catch (error) {
    // 失败
    ElMessage.error("保存spu失败");
  }
};

// 复制的upload
const dialogImageUrl = ref("");
const dialogVisible = ref(false);

// 删除图片成功调用的回调
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  // console.log(uploadFile, uploadFiles);
  spuImageList.value = uploadFiles as any;
};

// 点击图片的放大镜预览大图,我们不需要动
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

// 点击添加图片调用的回调
const handleSuccess: UploadProps["onSuccess"] = (
  response,
  uploadFile,
  uploadFiles
) => {
  // console.log(uploadFiles);
  spuImageList.value = uploadFiles as any;
};
</script>

<style lang="scss" scoped></style>